<?php
App::import('Model','categories.CmsCategory');
class ListCategory extends CmsCategory {

	var $name = 'ListCategory';
	var $frontendName = 'Category';
	
	var $order = array('ListCategory.order asc','ListCategory.name asc');
	var $actsAs = array(
					'Tree'=>array('__parentChange'=>true),
					'Cms.Sluggable'=>array('label'=>'name','slug'=>'slug','overwrite'=>true),
					'Upload' => array( 'icon'=>array(
							'dir' => '{WWW_ROOT}{DS}uploads{DS}category_icons',
							'empty'=>true,
							'slugPath'=>'ListCategory.name',
							'overwriteExisting'=>true,
							'mediaTypes'=>array(
								"Image"=>array(
								'resolution'=>array(
									'min'=>array('x'=>16,'y'=>16),
									'max'=>array('x'=>16,'y'=>16),)
								))
						
					)),
					'Cms.Metric'=>array(
									array('metric'=>'NumRecords', 'title' => 'Categories')
									
					)
			);
	var $hasMany = array(
					'Listing'=>array(
						'className'=>'Listing',
						'foreignKey'=>'list_category_id',
						'dependent'=>true),
					'Review'=>array(
						'className'=>'Review',
						'foreignKey'=>'list_category_id',
						'dependent'=>true)			
				);
				
	var	$belongsTo = array('ListingType');	
						
	function initialize()
	{
		$this->additionalFields[] = 'childrenCount';
		$this->additionalFields[] = 'viewUrl';
		$this->additionalFields[] = 'viewAdminUrl';
		$this->additionalFields[] = 'listingAddUrl';
		$this->additionalFields[] = 'listing_count';
		$this->additionalFields[] = 'parent_node_name';
		$this->additionalFields[] = 'file_url';
		$this->childrenModel = 'Listing';
		$this->setFieldProperties('icon',array('type'=>'file','group'=>array('add')));
		$this->setFieldProperties('listing_type_id',array('type'=>"select",'group'=>array('add'),'empty'=>__('-Select-'),'validate'=>array('rule'=>VALID_NOT_EMPTY,'required'=>true),'label'=>"Listing Type"));
		$this->cacheFields['childrenCount'] = 'onUpdate';
		$this->cacheFields['listing_count'] = 'onUpdate';
		$this->cacheFields['parent_node_name'] = 'onUpdate';
        $this->cacheFields['category_info'] = 'onUpdate';
		
		return parent::initialize();
	}
	
	function file_url($data)
	{
		$fileUrl = '/uploads/default_category_image.png';
		if(isset($data['ListCategory']['icon']) && $data['ListCategory']['icon'])
		{
			$fileUrl =  '/uploads/category_icons/'.$data['ListCategory']['icon'];
		}
		return $fileUrl;
	}
	
	function listing_count($record)
	{
		if(!isset($record[$this->alias]['id']))
		{
			return;
		}
		$childrenIds = $this->children($record[$this->alias]['id'],false,'id');
		$childrenIds = Set::extract('{n}.ListCategory.id',$childrenIds);
		array_push($childrenIds,$record[$this->alias]['id']);
		$listingCount = $this->Listing->find('count',array('conditions'=>array('Listing.list_category_id'=>$childrenIds,'Listing.status'=>Listing::PUBLISH)));
		if(cr('ListingConfig.allow_multiple_categories'))
        {
          $additionalCount = cri("AdditionalCategory")->getCategoryListingCount($childrenIds);
          $listingCount += $additionalCount;
        }
		return $listingCount;	
	}
	
	function parent_node_name($record)
	{
		if(!isset($record[$this->alias]['id']))
		{
			return false;
		}
		$parentId = $record[$this->alias]['parent_id'];
		$parentNodeName = __('N/A');
		if($parentId)
		{
			$parentNodeName = $this->field('name',array($this->alias.".id"=>$parentId));
		}
		return $parentNodeName;
		
	}
	
	function childrenCount($record)
	{
		if(!isset($record[$this->alias]['id']))
			return;
		return $this->childCount($record[$this->alias]['id'],true);
	}

	function viewUrl($result)
	{
		if(!isset($result['ListCategory']['slug']))
		{
			return false;
		}
		//@dynamic page interaction.
		$url = '/listings/index/category/category:'.$result['ListCategory']['slug'];
		return $url;
	}

	function viewAdminUrl($result)
	{
		if(!isset($result['ListCategory']['slug']))
		{
			return false;
		}
		//@dynamic page interaction.
		$url = '/admin/listings/index/category:'.$result['ListCategory']['id'];
		return $url;
	}
	
	function listingAddUrl($result)
	{
		$url = false;
		if(isset($result[$this->alias]['id']) && isset($result['ListCategory']['slug']))
		{
			$url = array('controller'=>"listings",'action'=>"add",$result[$this->alias]['id'],$result[$this->alias]['slug']);
		}
		return $url;
	}
	
	function afterSave($created)
	{
		GigaCache::delete('home_categories');
		GigaCache::delete('categories_options_all');
		GigaCache::delete('categories_options_with_slug');
		GigaCache::delete('category_dropdown_module_category_options');
		parent::afterSave($created);
		if(isset($this->data[$this->alias]['parent_id']))
        {
		  $this->clearCaheForListing($this->data[$this->alias]['parent_id']);
        }
	}
	
	function afterDelete()
	{
		GigaCache::delete('home_categories');
		GigaCache::delete('categories_options_all');
		GigaCache::delete('categories_options_with_slug');
		GigaCache::delete('category_dropdown_module_category_options');
		parent::afterDelete();		
	}
	/**
	 * Returns Custom fields for a model.
	 * @param unknown_type $id
	 * @param unknown_type $type
	 */
	function getCustomFields($id,$type = null)
	{
		$customFields = array();
		if($id)
		{
			$cacheOptions = (array('duration'=>"+1 day"));
			$cacheKey = $this->getCustomFieldsCacheKey($type);
			$customFields = null;//array();
			$customFields = GigaModelCache::read($this->alias,$id,$cacheKey,$cacheOptions);
			if(!is_array($customFields))
			{
				$listingTypeId = $this->field('listing_type_id',array($this->alias.'.id'=>$id));
				$customFields =  $this->ListingType->getCustomFields($listingTypeId,$type);
				if($type == Fieldset::TYPE_LISTING)
				{
					$reviewCustomFields = $this->getCustomFields($id,Fieldset::TYPE_REVIEW);
					
					$FieldPropertyObject = new GigaFieldProperties($reviewCustomFields);
					foreach($FieldPropertyObject->getFields('type',SCHEMA_TYPE_RATING) as $field)
					{
						$properties = $FieldPropertyObject->getProperties($field);
						$properties['validate'] = array();
						$properties['required'] = 0;
						$properties['group'] = array();
						$customFields[$field] = $properties;
					}
				}
				if(!$customFields)
				{
					$customFields = array();
				}
				GigaModelCache::write($this->alias,$id,$cacheKey,$customFields,$cacheOptions);
			}
		}
		return $customFields;
	}
	
	function getCustomFieldsCacheKey($type)
	{
		return 'custom_field_properties_'.low($type);	
	}
	
	function refreshListingTypeCache($listingTypeId)
	{
		$categories = $this->find('list',array('conditions'=>array('listing_type_id'=>$listingTypeId),'fields'=>array('id')));
		foreach($categories as $categoryId)
		{
			$this->removeCustomFieldsCache($categoryId);
		}
	}
	
	function removeCustomFieldsCache($id)
	{
		GigaModelCache::delete($this->alias,$id,$this->getCustomFieldsCacheKey(Fieldset::TYPE_LISTING));
		GigaModelCache::delete($this->alias,$id,$this->getCustomFieldsCacheKey(Fieldset::TYPE_REVIEW));
	}
	
	function getParentCategories() 
	{
		$cacheKey = 'home_categories';
		GigaCache::set(array('duration'=>"+1 hours",'path'=>CACHE));
		$cachedCategoryData = GigaCache::read($cacheKey);
		
		if($cachedCategoryData && !cr('DynamicPage.field'))
		{	
			$parentCategories = $cachedCategoryData;
		}else
		{
			$parentCategories = $this->find('all',array('conditions'=>array('parent_id'=>null),'recursive'=>-1));
			//dont't set cache if dynamic field
			if(!cr('DynamicPage.field'))
            {
              GigaCache::set(array('duration'=>"+1 hours",'path'=>CACHE));
              GigaCache::write($cacheKey,$parentCategories);
            }
		}
		return $parentCategories;	
	}

	
	function getVisibilityOptions()
	{
		$categories = $this->getOptionsWithSlug();
		return $categories;
	}

	
	function updateOrder($orders)
	{
		$orders = explode(',',$orders['orders']);
		$return  = false;
		$i = 1;
		foreach($orders as $categoryId)
		{
			if($this->hasAny(array('id'=>$categoryId)))
			{
				$this->id = $categoryId;				
				$this->saveField('order',$i);
			}
			$i++;
		}	
		$return =true;
	}
	
	function getOptionsWithSlug()
	{
		$key = "categories_options_with_slug";
		GigaCache::set(array('path'=>CACHE,'duration'=>"+1 day"));
		$options = GigaCache::read($key);
		if(!is_array($options))
		{
			$options =  $this->getChildrenOptionsWithSlug(null);
			GigaCache::set(array('path'=>CACHE,'duration'=>"+1 day"));
			GigaCache::write($key,$options);	
		}		
		return $options;
	}
	
	function getOptions($appearanceOptions = array())
	{		
		$key = "categories_options_all";
		GigaCache::set(array('path'=>CACHE,'duration'=>"+1 day"));
		$options = GigaCache::read($key);
		if(!is_array($options))
		{
			$options =  $this->getChildrenOptions(null, array(), $appearanceOptions);
			GigaCache::set(array('path'=>CACHE,'duration'=>"+1 day"));
			GigaCache::write($key,$options);	
		}		
		return $options;
	}	
	
	function getChildrenOptions($parenId,$parents = array(),$appearanceOptions = array())
	{
		$defaultAppearanceOptions = array('useUnderScore'=>false,'childrenSeparator'=>' > ');
		$appearanceOptions = am($defaultAppearanceOptions,$appearanceOptions);
		extract($appearanceOptions);
		$options = null;
		$cacheKey = "childrenoptions";
		$cacheTime = "+2 minutes";
		$options = GigaModelCache::read($this->alias, $parenId, $cacheKey, array("duration"=>$cacheTime));	
		if(!is_array($options))
		{
			$options = array();
			$categories = $this->find('list',array('conditions'=>array('parent_id'=>$parenId),'fields'=>array('id','name')));
			if($categories)
			{
				foreach($categories as $id => $name)
				{
					$labelArray = $parents;
					if($useUnderScore == true && $parents)
					{
						if(count($parents) > 1)
						{
							for($i = 1; $i <= count($parents); $i++)
							{
								$name = '_'.$name;
							}
						}else
						{
							$name = '_'.$name;
						}
						$labelArray = array();
					}

					$labelArray[] = $name;
					$label = implode($childrenSeparator,$labelArray);
					$options[$id] = $label;
					$childrenParents = am($parents,$name);
					$subOptions = $this->getChildrenOptions($id,$childrenParents,$appearanceOptions);
					if($subOptions)
					{
						foreach($subOptions as $key => $val)
						{
							$options[$key] = $val;
						}
					}
				}
			}
			GigaModelCache::write($this->alias, $parenId, $cacheKey, $options,array("duration"=>$cacheTime));
		}
		return $options;
	}	
	
	//@todo (1.1)  use Event handler.
	function clearCaheForListing($categoryId = null)
	{
		if($categoryId)
		{
			$this->clearRecordCache($categoryId);
			$parentCategories = $this->getpath($categoryId,'id');
			if(!empty($parentCategories))
			{
				foreach($parentCategories as $category)
				{
					$this->clearRecordCache($category['ListCategory']['id']);
				}
			}
			$this->clearRecordCache($categoryId);
		}
	}
	//@todo (1.1) repeated code of self::getChildrenOptions.
	function getChildrenOptionsWithSlug($parenId,$parents = array())
	{
		$options = array();
		$categories = $this->find('all',array('conditions'=>array('parent_id'=>$parenId),'fields'=>array('id','name','slug'),'recursive'=>-1));
		
		if($categories)
		{
			foreach($categories as $index => $category)
			{
				$category = $category['ListCategory'];
				$labelArray = $parents;
				$labelArray[] = $category['name'];
				$label = implode(' > ',$labelArray);
				$options[$category['slug']] = $label;
				$childrenParents = am($parents,$category['name']);
				$subOptions = $this->getChildrenOptionsWithSlug($category['id'],$childrenParents);
				if($subOptions)
				{
					foreach($subOptions as $key => $val)
					{
						$options[$key] = $val;
					}
				}
			}
		}
		return $options;
	}
	/**
	 * return a list of ids of categoryId and it's children in alphabetical order.
	 * @param $categoryId
	 */
	function getCategoryTreeList($parentId = null,$parents = array(),$appearanceOptions = array())
	{
		$categoryTree = $this->getChildrenOptions($parentId, array(), $appearanceOptions);
		return $categoryTree;			
	}	
	function getPathCategories($categoryId)
	{
		$cacheKey = "path_categories";
		$cacheOptions = array('path'=>CACHE,'duration'=>"+1 hour");
		$categories = GigaModelCache::read($this->alias,$categoryId,$cacheKey,$cacheOptions);
		if( $categories ===false)
		{
			$categories = $this->getPath($categoryId,array(),-1);	
			$categories = Set::extract('{n}.ListCategory.id',$categories);
			GigaModelCache::write($this->alias,$categoryId,$cacheKey,$categories,$cacheOptions);
		}
		return $categories;
	}
	
	function getTopParent($categoryId)
	{
		$pathCategories = $this->getPathCategories($categoryId);
		if($pathCategories)
		{
			$topCategoryId = array_shift($pathCategories);
		}else
		{
			$topCategoryId = $categoryId;
		}
		return $topCategoryId;
	}
	
	function getListingCount($category)
	{
		if(cr('DynamicPage.field'))
		{
			//@dynamic page interaction.
			$categoryId = $category[$this->alias]['id'];
			$fileName = GigaModelCache::FILE_PREFIX.cr('DynamicPage.field').'_'.cr('DynamicPage.value').'_'.$categoryId;
			$cacheOptions = array('path'=>CACHE,'duration'=>"+5 minutes",'fileName'=>$fileName);
			$cacheKey = "dynamic_page_listing_count";
			$listingCount = GigaModelCache::read($this->alias,$categoryId,$cacheKey,$cacheOptions);
			if($listingCount === false)
			{
				$listingCount = $this->listing_count($category);
				GigaModelCache::write($this->alias,$categoryId,$cacheKey,$listingCount,$cacheOptions);
			}
			
		}else
		{
			$listingCount = $category[$this->alias]['listing_count'];
		}
		return $listingCount;
	}
	
	function childrenList($parentId)
	{
		$cacheKey = "children_list";
		$childrenList = GigaModelCache::read($this->alias, $parentId, $cacheKey,array("duration"=>"+10 minutes"));
		if($childrenList === false)
		{
			$childrenList = $this->find("list",array("fields"=>array("id",'name'),'recursive'=>-1,'conditions'=>array("parent_id"=>$parentId)));
			GigaModelCache::write($this->alias,$parentId,$cacheKey,$childrenList,array("duration"=>"+10 minutes"));
		}
		return $childrenList;
	}
    
    function allowFieldCache($id, $field, $value)
    { 
      //ignore cacheing of listing count field.
      if(cr('DynamicPage.field') && $field == "listing_count")
      {
        return false;
      }
      return parent::allowFieldCache($id, $field, $value);
    }
    
   function getCategoryInfo($categoryId)
   {
        $cacheKey = "category_info";
        $category = GigaModelCache::read($this->alias,$categoryId,$cacheKey,array('duration'=>"+1 hour"));
        if(!is_array($category))
        {
            $this->recursive = -1;
            $category = $this->findById($categoryId);
            GigaModelCache::write($this->alias,$categoryId,$cacheKey,$category,array('duration'=>"+4 hour"));
        }
        return $category;
    }
	
}
?>